package com.bawei.hostapp.plugincore;

import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.util.Log;

import com.bawei.hostapp.ReflectUtils;
import com.bawei.hostapp.RegisteredActivity;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;


/**
 * @Author : yaotianxue
 * @Time : On 2023/6/6 08:11
 * @Description : HookUtils
 */
public class HookUtils {

    /**
     * hook AMS对象
     * 对AMS对象的startActivity方法拦截
     */
    public static void hookAms(Context context) throws NoSuchFieldException, ClassNotFoundException, IllegalAccessException {
        //1.获得AMS对象
        //1.1获得静态属性IActivityManagerSingleton
        Class<?> activityManagerClass = Class.forName("android.app.ActivityManager");
        Field iActivityManagerSingletonField = activityManagerClass.getDeclaredField("IActivityManagerSingleton");
        iActivityManagerSingletonField.setAccessible(true);
        Object iActivityManagerSingletonObject = iActivityManagerSingletonField.get(null);//静态变量通过null直接获取
        //1.2获得Single的mInstance属性值
        Class<?> singletonClazz = Class.forName("android.util.Singleton");
        Field mInstanceField = singletonClazz.getDeclaredField("mInstance");
        mInstanceField.setAccessible(true);
        Object AMSSubject = mInstanceField.get(iActivityManagerSingletonObject);//这就是AMS对象
        //2.对AMS对象进行代理动态代理:代理对象和被代理对象同一个接口IActivityManager
        Class<?> IActivityManagerInterface = Class.forName("android.app.IActivityManager");
        AMSInvocationHandler handler = new AMSInvocationHandler(context, AMSSubject);
        Object AMSProxy = Proxy.newProxyInstance(//动态代理，交给AMSInvocationHandler处理
                Thread.currentThread().getContextClassLoader(),
                new Class[]{IActivityManagerInterface},
                handler
        );
        mInstanceField.set(iActivityManagerSingletonObject,AMSProxy);
        //3.InvocationHandler对AMS对象的方法进行拦截
    }

    public static final String  TAG = "ytx";
    public static boolean hookAmS(Context context){
        // 系统是9.0及以下，获取IActivityManager单例对象
        if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.P){
            Log.e(TAG,"api <= 25，start hook AMS !!!");
            Object singleton = null;
            // 系统是7.1及以下，获取IActivityManager单例的类名是ActivityManagerNative，属性名是gDefault
            if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1){
                Class<?> clazz = ReflectUtils.getClass("android.app.ActivityManagerNative");
                Object gDefault = ReflectUtils.getStaticFieldValue(clazz,"gDefault");
                singleton = gDefault;
                if(singleton == null){
                    // api <= 25，get gDefault failed
                    Log.e(TAG,"api <= 25，get gDefault failed !!!");
                    return false;
                }
            }
            // 系统是9.0及以下，获取IActivityManager单例的类名是ActivityManager，属性名是IActivityManagerSingleton
            else{
                Log.e(TAG,"api <= 28，start hook AMS !!!");
                Object IActivityManagerSingleton = ReflectUtils.getStaticFieldValue(ActivityManager.class,"IActivityManagerSingleton");
                singleton = IActivityManagerSingleton;
                if(singleton == null){
                    // api <= 25，get IActivityManagerSingleton failed
                    Log.e(TAG,"api <= 28，get IActivityManagerSingleton failed !!!");
                    return false;
                }
            }
            // 获取单例对象的实例，也就是AMS
            Object AMSObject = ReflectUtils.getFieldValue(singleton,"mInstance");
            Class<?> IActivityManagerClazz = ReflectUtils.getClass("android.app.IActivityManager");
            // 对AMS对象进行动态代理，拦截startActivity方法，将Intent参数替换成宿主的Activity
            Object AMSProxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{IActivityManagerClazz},new AMSInvocationHandler(context,AMSObject));
            // 将动态代理实例设置给单例
            boolean success = ReflectUtils.setField(singleton,"mInstance",AMSProxy);
            if(!success){
                Log.e(TAG,"api <= 28，AMS hook failed !!!");
            }
            return success;
        }
        // 系统是12及以下，获取IActivityTaskManager单例对象，API29开始将单独提取出了ActivityTaskManager来管理Activity
        else{
            Log.e(TAG,"api <= 32，start hook A(T)MS !!!");
            // 获取ActivityTaskManager类的静态属性IActivityTaskManagerSingleton，是一个单例
            Class<?> clazz = ReflectUtils.getClass("android.app.ActivityTaskManager");
            Object IActivityTaskManagerSingleton = ReflectUtils.getStaticFieldValue(clazz,"IActivityTaskManagerSingleton");
            // 获取单例的实例，即A(T)MS对象
            Object AMSObject = ReflectUtils.getFieldValue(IActivityTaskManagerSingleton,"mInstance");
            Class<?> IActivityTaskManagerClazz = ReflectUtils.getClass("android.app.IActivityTaskManager");
            // 对A(T)MS对象进行动态代理，拦截startActivity方法，将Intent参数替换成宿主的Activity
            Object AMSProxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{IActivityTaskManagerClazz}, new AMSInvocationHandler(context,AMSObject));
            // 将动态代理实例设置给单例
            boolean success = ReflectUtils.setField(IActivityTaskManagerSingleton,"mInstance",AMSProxy);
            if(!success){
                Log.e(TAG,"api > 28，AMS hook failed !!!");
            }
            return success;
        }
    }





    /**
     * 获得到handler特定消息中的Intent进行处理
     * 将Intent对象的RegisteredActivity替换成PluginActvity
     */
    public static void hookHandler(Context context) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //1。获取到handler对象
        Class<?>  activityThreadClass = Class.forName("android.app.ActivityThread");
        Field sCurrentActivityThreadField =  activityThreadClass.getDeclaredField("sCurrentActivityThread");
        sCurrentActivityThreadField.setAccessible(true);
        Object activityThreadObject = sCurrentActivityThreadField.get(null);//静态直接给null即可
        Field mHField = activityThreadClass.getDeclaredField("mH");
        mHField.setAccessible(true);
        Object mHObject = mHField.get(activityThreadObject);
        //2.给handler的mCallback的属性进行赋值，静态代理实现
        Field mCallbackField = Handler.class.getDeclaredField("mCallback");
        mCallbackField.setAccessible(true);
        mCallbackField.set(mHObject,new HookHmCallback());
        //3.在callback中将Intent对象的RegisberedActivity替换成PluginActvity
    }

//    public static void hookHandler(Context context){
//        // 拦截AMS检查完成之后的消息，将启动Activity的消息拦截，将消息中的Intent替换会插件Activity
//        // 获取ActivityThread类
//        Class<?> activityThreadClazz = ReflectUtils.getClass("android.app.ActivityThread");
//        // 获取ActivityThread的静态属性sCurrentActivityThread，也是它自己的实例
//        Object activityThreadObject = ReflectUtils.getStaticFieldValue(activityThreadClazz,"sCurrentActivityThread");
//        // 获取ActivityThread实例的mH属性，是一个Handler消息处理器
//        Object mHObject = ReflectUtils.getFieldValue(activityThreadObject,"mH");
//        // 设置Handler的实例属性mCallback为HookHmCallback，在其中进行消息拦截
//        boolean success = ReflectUtils.setField(mHObject,"mCallback",new HookHmCallback());
//        if(!success){
//            Log.e(TAG,"api > 28，Handler hook failed !!!");
//        }
//
//    }
}
